package com.jc.order.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.jc.order.constant.OrderConst;
import com.jc.order.domain.KjbExchangeRate;
import com.jc.order.dto.ExchangeRateDTO;
import com.jc.order.mapper.KjbExchangeRateMapper;
import com.jc.order.service.ExchangeRateService;
import com.jc.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Optional;

@Service
@Slf4j
public class ExchangeRateServiceImpl implements ExchangeRateService {
    @Resource
    private KjbExchangeRateMapper kjbExchangeRateMapper;

    @Override
    public ExchangeRateDTO getExchangeRateByDateAndCode(Date date, String code) {

        ExchangeRateDTO exchangeRateDTO = null;
        Example example = new Example(KjbExchangeRate.class);
        example.createCriteria().andEqualTo("rateDate", DateUtil.format(date, DatePattern.NORM_DATE_PATTERN)).andEqualTo("code", code);
        KjbExchangeRate exchangeRate = kjbExchangeRateMapper.selectOneByExample(example);
        if (exchangeRate != null) {
            exchangeRateDTO = new ExchangeRateDTO();
            BeanUtils.copyProperties(exchangeRate, exchangeRateDTO);

        }
        return exchangeRateDTO;
    }


    /**
     * 带错误处理的汇率获取方法
     *
     * @param currency 货币代码
     * @return 有效汇率，若无效会自动设置错误信息并返回null
     */
    @Override
    public Result<BigDecimal> getExchangeRate(String currency) {
        Result<BigDecimal> r =new Result<>();
        fetchExchangeRate(currency)
                .map(rate -> {
                    log.debug("成功获取 {} 汇率: {}", currency, rate);
                    r.ok().setContent(rate);
                    return rate;
                })
                .orElseGet(() -> {
                    r.error();
                    handleExchangeRateError(currency, r);
                    return  null;
                });
       return r;
    }

    /**
     * 获取有效汇率（返回Optional包装对象）
     *
     * @param currency 货币代码
     * @return Optional包含有效汇率，empty表示无效货币或未找到汇率
     */
    private Optional<BigDecimal> fetchExchangeRate(String currency) {
        if (isChineseYuan(currency)) {
            return Optional.of(BigDecimal.ONE);
        }

        return Optional.ofNullable(currency)
                .filter(StrUtil::isNotBlank)
                .map(code -> this.getExchangeRateByDateAndCode(DateUtil.date(), code))
                .map(this::convertRateValue);
    }


    /**
     * 转换汇率值（服务DTO -> BigDecimal）
     */
    private BigDecimal convertRateValue(ExchangeRateDTO dto) {
        final BigDecimal divisor = new BigDecimal("100");
        final int scale = 4;
        return dto.getZhesuan()
                .divide(divisor, scale, RoundingMode.HALF_UP)
                .setScale(scale, RoundingMode.HALF_UP);
    }

    /**
     * 处理汇率错误情况
     */
    private void handleExchangeRateError(String currency, Result<?> result) {
        String errorMessage = StrUtil.isBlank(currency) ?
                "货币代码不能为空" :
                String.format("没有查到[%s]有效的汇率信息", currency);

        log.warn(errorMessage);
        result.error().setMessage(errorMessage);
    }

    /**
     * 判断是否人民币货币
     */
    private boolean isChineseYuan(String currency) {
        return StrUtil.isNotBlank(currency) &&
                (currency.equalsIgnoreCase(OrderConst.CURRENCY_CNY) || currency.equalsIgnoreCase(OrderConst.CURRENCY_RMB));
    }


}
